package com.kun.gulimall.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import java.util.Map;

/**
 * 查询参数
 */
public class Query<T> {

    public static <T> IPage<T> getIBean(Object object, Class<T> clazz) {
        Map<String, Object> params = BeanUtil.beanToMap(object);
        return new Query<T>().getPage(params);
    }

    public IPage<T> getPage(Map<String, Object> params) {
        return this.getPage(params, null, false);
    }

    public IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc) {
        String pageContext = "page";
        String limitContext = "limit";
        //分页参数
        long curPage = 1;
        long limit = 10;

        Object pageI = params.get(pageContext);
        if (pageI != null) {
            if (pageI instanceof Integer page2) {
                curPage = page2.longValue();
            } else {
                curPage = Long.parseLong((String) pageI);
            }
        }
        Object pageII = params.get(limitContext);
        if (pageII != null) {
            if (pageII instanceof Integer page3) {
                limit = page3.longValue();
            } else {
                limit = Long.parseLong((String) pageII);
            }
        }

        //分页对象
        Page<T> page = new Page<>(curPage, limit);

        //分页参数
        params.put(pageContext, page);

        //排序字段
        //防止SQL注入（因为sidx、order是通过拼接SQL实现排序的，会有SQL注入风险）
        String orderField = sqlInject((String) params.get("sidx"));
        String order = (String) params.get("order");


        //前端字段排序
        if (StrUtil.isNotEmpty(orderField) && StrUtil.isNotEmpty(order)) {
            if ("asc".equalsIgnoreCase(order)) {
                return page.addOrder(OrderItem.asc(orderField));
            } else {
                return page.addOrder(OrderItem.desc(orderField));
            }
        }

        //没有排序字段，则不排序
        if (StrUtil.isBlank(defaultOrderField)) {
            return page;
        }

        //默认排序
        if (isAsc) {
            page.addOrder(OrderItem.asc(defaultOrderField));
        } else {
            page.addOrder(OrderItem.desc(defaultOrderField));
        }

        return page;
    }

    public static String sqlInject(String str) {
        if (StrUtil.isBlank(str)) {
            return null;
        }

        // 去掉特殊字符
        str = StrUtil.replace(str, "'", "");
        str = StrUtil.replace(str, "\"", "");
        str = StrUtil.replace(str, ";", "");
        str = StrUtil.replace(str, "\\", "");

        // 转换为小写
        str = str.toLowerCase();

        // 定义非法关键词
        String[] keywords = {"master", "truncate", "insert", "select", "delete", "update", "declare", "alter", "drop"};

        for (String keyword : keywords) {
            if (StrUtil.contains(str, keyword)) {
                throw new RuntimeException("包含非法字符: " + keyword);
            }
        }

        return str;
    }

}
